package com.cy.ppj.web.front;

import com.cy.ppj.comm.constant.Constants;
import com.cy.ppj.comm.utils.CommonUtils;
import com.cy.ppj.model.Result;
import com.cy.ppj.model.ao.bankma.BankmaCustomerAddAO;
import com.cy.ppj.model.ao.order.OrderScanRecordAddAO;
import com.cy.ppj.model.ao.sms.SmsCodeAO;
import com.cy.ppj.model.ao.user.UserLoginAO;
import com.cy.ppj.model.ao.user.UserRegisterAO;
import com.cy.ppj.model.domian.bankma.BankmaCustomer;
import com.cy.ppj.model.domian.city.City;
import com.cy.ppj.model.domian.product.Product;
import com.cy.ppj.model.domian.user.User;
import com.cy.ppj.model.domian.user.UserWechat;
import com.cy.ppj.model.dto.order.OrderAddDTO;
import com.cy.ppj.model.dto.customer.CustomerOrderScanRecordDTO;
import com.cy.ppj.model.dto.user.UserAddDTO;
import com.cy.ppj.model.dto.user.UserLoginDTO;
import com.cy.ppj.model.enums.MessageType;
import com.cy.ppj.model.enums.OrderStatus;
import com.cy.ppj.model.enums.ProductAttachmentType;
import com.cy.ppj.model.enums.SmsType;
import com.cy.ppj.model.enums.UserType;
import com.cy.ppj.model.vo.ProductExtendPathVO;
import com.cy.ppj.service.account.CertificationService;
import com.cy.ppj.service.account.UserInfoService;
import com.cy.ppj.service.bankma.BankmaCustomerService;
import com.cy.ppj.service.city.CityService;
import com.cy.ppj.service.comm.SmsService;
import com.cy.ppj.service.message.MessageService;
import com.cy.ppj.service.order.OrderService;
import com.cy.ppj.service.product.ProductService;
import com.cy.ppj.service.user.UserService;
import com.cy.ppj.service.user.UserWechatService;
import com.cy.ppj.web.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @description: 首页
 * @author: Ocean
 * @create: 2018-07-19 19:42
 **/
@Slf4j
@RestController
@Api(tags = "前台-首页")
@RequestMapping("/home")
public class HomeController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private UserWechatService userWechatService;
    @Autowired
    private ProductService productService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CityService cityService;
    @Autowired
    private BankmaCustomerService bankmaCustomerService;
    @Autowired
	private CertificationService certificationService;
    @Autowired
    private UserInfoService userInfoService;

    @ApiOperation("用户注册")
    @PostMapping("/register")
    public Result register(@Validated UserRegisterAO userRegisterAO, BindingResult bindingResult) {
        this.checkError(bindingResult);
        this.checkSmsCode(userRegisterAO.getMobile(), userRegisterAO.getSmsCode(), SmsType.USER_REGISTER);
        UserAddDTO userAddDTO = new UserAddDTO();
        BeanUtils.copyProperties(userRegisterAO, userAddDTO);
        userAddDTO.setUserType(UserType.CHANNEL);
        userService.insertUser(userAddDTO);

        //渠道员注册发送消息
        messageService.sendMessage(userRegisterAO.getMobile(), MessageType.USER_REGISTER);

        return ok();
    }

    /**
     * token登录
     *
     * @param token
     * @return
     */
    @GetMapping("/login")
    public Result<UserLoginDTO> loginInfo(@RequestParam String token) {
        UserLoginDTO user = this.getUser(token);
        return ok(null, user);
    }

    @ApiOperation("用户登录")
    @PostMapping("/login")
    public Result login(@Validated UserLoginAO userLoginAO, BindingResult bindingResult, HttpServletRequest request, HttpServletResponse response) {

        this.checkError(bindingResult);
        Result result = userService.login(userLoginAO.getMobile(), userLoginAO.getPassword());

        if (!result.isOk() || !CommonUtils.isWechatClient(request)) {
        	//登录失败、或者不是从微信进行登录网页的，直接返回登录结果
            return result;
        }
        UserLoginDTO user = (UserLoginDTO) result.getValue();
        UserWechat userWechat = userWechatService.queryByUserIdInCache(user.getUserId());
        if (userWechat == null || !userWechat.getManualBind()) {
            user.setBind(false);
        }
        return result;
    }


    @ApiOperation("发送短信验证码")
    @PostMapping("/send/sms/code")
    public Result sendSmsCode(@Validated SmsCodeAO smsCodeAO, BindingResult bindingResult) {

        this.checkError(bindingResult);

        String key = CommonUtils.smsCodeKey(smsCodeAO.getMobile(), smsCodeAO.getSmsType());
        if (redisTemplate.hasKey(key)) {
            return ok("验证码已发送", redisTemplate.getExpire(key, TimeUnit.SECONDS));
        }

        String code = Constants.IS_PROD ? CommonUtils.randomCode(4) : "8888";
        Map<String, Object> params = new HashMap<>();
        params.put("code", code);
        Result result = smsService.send(smsCodeAO.getMobile(), smsCodeAO.getSmsType(), params);
        if (result.isOk()) {
            redisTemplate.opsForValue().set(key, code, 10, TimeUnit.MINUTES);
            result.setValue(10 * 60);
        }

        return result;
    }

    @ApiOperation("重置密码")
    @PostMapping("/reset/password")
    public Result resetPassword(@ApiParam(value = "手机号码", required = true) @RequestParam String mobile,
                                @ApiParam(value = "验证码", required = true) @RequestParam String code,
                                @ApiParam(value = "新密码", required = true) @RequestParam String newPassword) {
        //验证验证码
        this.checkSmsCode(mobile, code, SmsType.PASSWORD_RESET);
        //重置密码操作
        userService.resetPassword(mobile, newPassword);
        return ok();
    }

    @ApiOperation("获取产品推广页面图片地址")
    @GetMapping("/get/product/extend/page/url")
    public Result getProductExtendPageUrl(@ApiParam(value = "产品ID", example = "0", required = true) @RequestParam Long productId) {
    	ProductExtendPathVO model = productService.selectPathByProductIdAndType(productId, ProductAttachmentType.EXTEND_PAGE);
    	return ok("获取成功", model.getPagePath());
    }
    
    @ApiOperation("添加订单浏览记录")
    @PostMapping("/add/order/scan/record")
    public Result addOrderScanRecord(@Validated OrderScanRecordAddAO orderScanRecordAddAO, BindingResult bindingResult) {
    	this.checkError(bindingResult);
    	
    	// 限制
    	CustomerOrderScanRecordDTO customerOrderScanRecordDTO = orderService.selectCustomerOrderScanRecordDTO(orderScanRecordAddAO.getIdNo(), orderScanRecordAddAO.getProductId());
    	if(customerOrderScanRecordDTO != null) {
    		if(customerOrderScanRecordDTO.getApplyCount() > 0) {
    			// 如果有同一个idNo、同一个产品的浏览记录，判断提交的时间，24小时之内就不新增新的浏览记录，超过24小时，则新增一条新的浏览记录数据
    			int days = CommonUtils.diffDays(customerOrderScanRecordDTO.getApplyTime(), new Date());
    			if(days <= 1) {
    				Product product = new Product();
    		    	product.setId(orderScanRecordAddAO.getProductId());
    		    	product = productService.selectProduct(product);
    		    	String sourceUrl = product.getSourceUrl();
    		    	return ok("添加成功", sourceUrl);
    			}
    		}
    	}
    	//获取经纪人用户
    	User user = new User();
    	user.setMobile(orderScanRecordAddAO.getBrokerMobile());
    	user = userService.selectUser(user);
    	//添加订单浏览记录
    	OrderAddDTO orderAddDTO = new OrderAddDTO();
    	BeanUtils.copyProperties(orderScanRecordAddAO, orderAddDTO);
    	orderAddDTO.setUserId(user.getId());
    	orderAddDTO.setOrderStatus(OrderStatus.APPLY);
    	Result addOrderResult = orderService.addOrder(orderAddDTO);
    	//发送微信消息模板
        messageService.sendMessage(String.valueOf(addOrderResult.getValue()), MessageType.ADD_ORDER_SCAN_RECORD);
    	//添加成功之后，查找产品方地址
    	Product product = new Product();
    	product.setId(orderScanRecordAddAO.getProductId());
    	product = productService.selectProduct(product);
    	String sourceUrl = product.getSourceUrl();
    	return ok("添加成功", sourceUrl);
    }
    
    @ApiOperation("获取用户微信头像地址")
    @GetMapping("/get/user/head/img")
    public Result getUserHeadImg(@ApiParam(value = "用户手机号码", required = true) @RequestParam String mobile) {
    	User user = new User();
    	user.setMobile(mobile);
    	user = userService.selectUser(user);
    	return ok("", user.getHeadImg());
    }
    
    @ApiOperation("获取城市列表")
    @GetMapping("/city/list")
    public Result cityList() {
    	List<City> list = cityService.getAllCityInCache();
    	return ok("", list);
    }
    
    @ApiOperation("新增bankma马先生官网咨询客户信息")
    @PostMapping("/do/add/bankma/customer")
    public Result addBankmaCustomer(@Validated BankmaCustomerAddAO addAO, BindingResult bindingResult) {
    	this.checkError(bindingResult);
    	BankmaCustomer bankmaCustomer = new BankmaCustomer();
    	BeanUtils.copyProperties(addAO, bankmaCustomer);
    	bankmaCustomerService.addBankmaCustomer(bankmaCustomer);
    	return ok();
    }
    
    @ApiOperation("实名认证")
    @PostMapping("/certification")
    public Result<Map<String, String>> certification(String name, String idCard) {
    	return certificationService.certificationIdCard(name, idCard);
    }
    
    @ApiOperation("post传递form表单参数")
    @PostMapping("/post/form")
    public Result postForm(@RequestParam(value = "name") String name, @RequestParam(value = "mobile") String mobile,
    		@RequestParam(value = "age") String age) {
    	Map<String, String> map = new HashMap<>();
    	map.put("name", name);
    	map.put("mobile", mobile);
    	map.put("age", age);
    	
    	return ok("", map);
    }
    
    @ApiOperation("post传递json参数")
    @PostMapping("/post/json")
    public Result postForm(@RequestBody Map<String, Object> map) {
    	
    	return ok("", map);
    }

    @ApiOperation("遍历所有的白银升级为黄金")
    @GetMapping("/toGolden")
    public Result toGolden() {

        userInfoService.batchUpdateUserInfoToGolden();
        return ok();
    }

    @ApiOperation("遍历所有的黄金升级为钻石")
    @GetMapping("/toDiamond")
    public Result toDiamond() {

        userInfoService.batchUpdateUserInfoToDiamond();
        return ok();
    }
}
